﻿//
// Copyright (c) 2024 BPer
//
#include <bperrtc/BPerDatachannel.h>

#include <bperssl/BPerRtcDtls.h>
#include <bperutil/sys/BPerLog.h>
#include <bperutil/sys/BPerSctp.h>

#if BPer_Enable_Datachannel
typedef struct{
	BPerSctp sctp;
	BPerRtcDtls* dtls;
}BPerDatachannelContext;

#define BPer_Sctp_BufferLen 8192

void bPer_datachannel_on_message(void *pcontext,char* data,int32_t nb){
	BPerDatachannelContext* context=(BPerDatachannelContext*)pcontext;
	bPer_sctp_receiveData(&context->sctp,data,nb);
}

void bPer_datachannel_send_message(void *pcontext,BPerFrame* msgFrame){
	BPerDatachannelContext* context=(BPerDatachannelContext*)pcontext;
	bPer_sctp_sendData(&context->sctp,msgFrame);
}


void bPer_datachannel_receive_msg(void* user,uint16_t streamId, uint16_t ssn, uint32_t ppid, int flags,  uint8_t* data, size_t len){
	BPerRtcContext* context=(BPerRtcContext*)user;

	BPerFrame frame;
	bPer_memset(&frame,0,sizeof(BPerFrame));
	frame.payload=data;
	frame.nb=len;
	frame.uid=context->streamConfig->uid;
    context->streamConfig->recvCallback.receiveMsg(context->streamConfig->recvCallback.context,&frame);
}

void bPer_datachannelsend_dtls_msg(void* user,char* data,int32_t nb){
	if(user==NULL||data==NULL) return;

	BPerRtcContext* context=(BPerRtcContext*)user;
	if(context->dtls->session.state!=BPerDtlsStateClientDone||context->dtls->session.isRecvAlert||context->state!=BPer_Conn_State_Connected)	return;

	context->dtls->sendSctpData(&context->dtls->session,(uint8_t*)data,nb);
}

void bPer_create_datachannel(BPerDatachannel *datachannel,BPerRtcContext* ctx){
	if(datachannel==NULL) return;
	BPerDatachannelContext* context=(BPerDatachannelContext*)bPer_calloc(sizeof(BPerDatachannelContext),1);
	datachannel->context=context;
	context->dtls=ctx->dtls;
	bPer_create_sctp(&context->sctp);
	context->sctp.user=ctx;
	context->sctp.send_dtls_msg=bPer_datachannelsend_dtls_msg;
	context->sctp.receive_msg=bPer_datachannel_receive_msg;


	datachannel->on_message=bPer_datachannel_on_message;
	datachannel->send_message=bPer_datachannel_send_message;
}

void bPer_destroy_datachannel(BPerDatachannel *datachannel){
	if(datachannel==NULL||datachannel->context==NULL) return;
	BPerDatachannelContext* context=(BPerDatachannelContext*)datachannel->context;
	bPer_destroy_sctp(&context->sctp);
}
#endif
